/**
 * 
 */
package de.coe.hendricjabs.friendmap.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.commons.io.IOUtils;

/**
 * @author Hendric
 * 
 */
public class MapServer implements Runnable {

    protected int serverPort = 999;
    protected ServerSocket serverSocket = null;
    protected boolean isStopped = false;
    protected Thread runningThread = null;

    /**
     * 
     */
    public MapServer() {

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Port: ");
        int port;;
        try {
            port = Integer.valueOf(new BufferedReader(new InputStreamReader(System.in)).readLine());
        } catch (IOException e1) {
            port = 999;
            e1.printStackTrace();
        }
        MapServer server = new MapServer(port);
        System.out.println("Lausche auf Port " + port);
        Thread t = new Thread(server);
        t.start();
        try {
            t.join();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("Beenden mit q");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            while (true) {
                if (in.read() == 'q') {
                    server.stop();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public MapServer(int port) {
        this.serverPort = port;
    }

    public void run() {
        synchronized (this) {
            this.runningThread = Thread.currentThread();
        }
        openServerSocket();
        while (!isStopped()) {
            Socket clientSocket = null;
            try {
                clientSocket = this.serverSocket.accept();
            } catch (IOException e) {
                if (isStopped()) {
                    System.out.println("Server Stopped.");
                    return;
                }
                throw new RuntimeException("Error accepting client connection", e);
            }
            new Thread(new WorkerRunnable(clientSocket, "Multithreaded Server")).start();
        }
        System.out.println("Server Stopped.");
    }

    private synchronized boolean isStopped() {
        return this.isStopped;
    }

    public synchronized void stop() {
        this.isStopped = true;
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }

    private void openServerSocket() {
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
            serverSocket.setReuseAddress(true);
        } catch (IOException e) {
            IOUtils.closeQuietly(serverSocket);
            throw new RuntimeException("Cannot open port " + this.serverPort, e);
        }
    }
}
